<template>
  <q-dialog v-model="visible" persistent>
    <q-card style="max-width: 90vw; max-height: calc(100vh - 2rem)">
      <q-card-section class="flex">
        <div class="text-h6">{{ modify ? "修改" : "新增" }}动作</div>
        <q-space />
        <q-btn icon="close" dense flat round v-close-popup />
      </q-card-section>
      <q-separator />
      <div style="max-height: calc(100vh - 10rem); overflow-y: auto">
        <q-card-section class="q-gutter-y-sm">
          <q-input v-model="action.priority" outlined label="优先度" />
          <amr-selector
            outlined
            label="目标设备"
            :disable="device != null"
            v-model="action.device"
            @full="setAmrType"
          />
          <q-select
            outlined
            v-model="action.actionGroup"
            :options="groups"
            label="动作分组"
            behavior="menu"
            emit-value
            @popup-hide="groupChange"
            map-options
          />
          <q-select
            outlined
            v-model="action.type"
            :options="actionTypes"
            label="动作类型"
            behavior="menu"
            emit-value
            @popup-hide="typeChange"
            map-options
          />
          <q-slide-transition>
            <map-pose-selector
              v-if="action.type.includes('move')"
              v-model="action.data"
            />
            <map-pose-selector
              v-else-if="
                ['lift-in', 'lift-exit'].includes(action.type) &&
                action.actionGroup === 'amr'
              "
              v-model="action.data"
            />
            <q-input
              v-else-if="action.type === 'still'"
              outlined
              label="等待秒数"
              v-model="action.data"
              type="number"
            />
            <q-select
              v-else-if="action.type === 'music'"
              outlined
              v-model="action.data"
              label="音乐开关"
              :options="booleanOption"
              map-options
              emit-value
            />
            <div v-else-if="action.type === 'cruise'" class="q-gutter-y-sm">
              <q-input v-model="action.data.circle" outlined label="巡航圈数" />
              <q-input v-model="action.data.still" outlined label="等待秒数" />
              <q-select
                outlined
                v-model="action.data.type"
                :options="basicMove"
                label="运动指令类型"
                emit-value
                map-options
              />
              <q-select
                outlined
                v-model="action.data.music"
                label="播放音乐"
                :options="booleanOption"
                map-options
                emit-value
              />
            </div>
            <div
              v-else-if="['load', 'unload'].includes(action.type)"
              class="q-pl-sm q-pr-sm q-pb-sm q-gutter-y-sm q-card--bordered"
            >
              <q-input
                filled
                v-model="action.data.specs"
                outlined
                label="规格"
              />
              <template v-if="action.actionGroup === 'transport-as-rs'">
                <q-input
                  v-model="action.data.level"
                  outlined
                  label="层数"
                  type="number"
                />
                <map-pose-selector
                  v-model="action.data.poseID"
                  filter="station-port"
                  label="选择工位点"
                />
              </template>
              <template v-else-if="action.actionGroup === 'transport-catch'">
                <q-input
                  filled
                  v-model="action.data.count"
                  outlined
                  label="货物数量"
                  type="number"
                />
                <map-pose-selector
                  filled
                  v-model="action.data.poseID"
                  filter="catch"
                  label="选择工位点"
                />
                <posture-selector
                  filled
                  v-if="action.actionGroup === 'transport-catch'"
                  v-model="action.data.posture"
                />
              </template>
            </div>
            <div
              v-else-if="['lift-in', 'lift-out'].includes(action.type)"
              class="q-pl-sm q-pr-sm q-pb-sm q-gutter-y-sm q-card--bordered"
            >
              <q-input
                filled
                v-model="action.data.specs"
                outlined
                label="规格"
              />
              <q-input
                filled
                v-model="action.data.level"
                outlined
                label="层数"
                type="number"
              />
              <map-pose-selector
                filled
                v-model="action.data.poseID"
                filter="station-lift"
                label="选择工位点"
              />
            </div>
            <map-pose-selector
              filled
              v-else-if="action.type === 'detach'"
              v-model="action.data"
              label="选择点位"
            />
            <div
              v-else-if="['attach'].includes(action.type)"
              class="q-pl-sm q-pr-sm q-pb-sm q-gutter-y-sm q-card--bordered"
            >
              <q-select
                filled
                v-model="configs.place"
                label="进工位方向"
                :options="placeOption"
                map-options
                emit-value
              />
              <map-pose-selector
                filled
                v-model="configs.poseID"
                filter="station-port"
                label="选择立体库"
              />
            </div>
            <div
              v-else-if="['operate'].includes(action.type)"
              class="q-pl-sm q-pr-sm q-pb-sm q-gutter-y-sm q-card--bordered"
            >
              <q-select
                filled
                v-model="configs.type"
                label="操作类型"
                :options="[
                  { label: '取料', value: 'LOAD' },
                  { label: '放料', value: 'UNLOAD' },
                ]"
                map-options
                emit-value
              />
              <q-select
                filled
                v-model="configs.place"
                label="进工位方向"
                :options="placeOption"
                map-options
                emit-value
              />
              <map-pose-selector
                filled
                v-model="configs.poseID"
                filter="station-port"
                label="选择立体库"
              />
            </div>
            <div
              v-else-if="['posture'].includes(action.type)"
              class="q-pl-sm q-pr-sm q-pb-sm q-gutter-y-sm q-card--bordered"
            >
              <q-select
                filled
                v-model="configs.type"
                label="移动类型"
                :options="[
                  { label: '关节', value: 'joint' },
                  { label: '直线', value: 'linear' },
                ]"
                map-options
                emit-value
              />
              <posture-selector
                filled
                v-if="action.actionGroup === 'transport-catch'"
                v-model="configs.poseID"
                type="normal"
              />
            </div>
            <q-input
              v-else-if="action.type === 'lift'"
              v-model="action.data"
              outlined
              label="顶升参数"
            />
            <q-input
              v-else-if="action.type === 'fork'"
              v-model="action.data"
              outlined
              label="叉车机构参数"
            />
            <shelf-selector
              v-else-if="['fork-in', 'fork-out'].includes(action.type)"
              label="目标货架"
              v-model="action.data"
            />
            <q-input outlined label="指令内容" v-model="action.data" v-else />
          </q-slide-transition>
        </q-card-section>
      </div>
      <q-slide-transition v-if="modify">
        <q-card-section class="q-pa-none row" v-if="modified || modifiedConfig">
          <q-btn
            stretch
            color="primary"
            class="col"
            label="修改动作"
            @click="update"
          />
          <q-btn
            stretch
            color="secondary"
            class="col"
            label="还原动作"
            @click="reset"
          />
        </q-card-section>
        <q-card-section class="q-pa-none row" v-else>
          <q-btn
            stretch
            color="primary"
            class="col"
            label="立即执行"
            @click="execute"
          />
          <q-btn
            stretch
            color="negative"
            class="col"
            label="删除动作"
            @click="remove"
          />
        </q-card-section>
      </q-slide-transition>
      <q-slide-transition v-else>
        <div v-show="!incomplete" class="bg-primary">
          <q-btn
            unelevated
            class="full-width text-subtitle1 text-bold"
            color="primary"
            label="新增动作"
            @click="addAction"
          />
        </div>
      </q-slide-transition>
    </q-card>
  </q-dialog>
</template>

<script>
import { ref, computed, inject } from "vue";
import { api } from "boot/axios";
import { useQuasar } from "quasar";
import { useAPIStore } from "stores/api/index.js";

import MapPoseSelector from "components/actionPlan/MapPoseSelector.vue";
import AmrSelector from "components/actionPlan/AmrSelector.vue";
import PostureSelector from "components/actionPlan/PostureSelector.vue";
import ShelfSelector from "components/actionPlan/ShelfSelector.vue";

const booleanOption = [
  { label: "关闭", value: false },
  { label: "开启", value: true },
];

export default {
  name: "ModifyAction",
  components: { ShelfSelector, PostureSelector, AmrSelector, MapPoseSelector },
  props: {
    modify: { type: Boolean, default: false },
    priority: Number,
    device: String,
    plan: Object,
  },
  setup(props, context) {
    const $q = useQuasar();
    const visible = ref(false);
    const action = ref({
      device: "",
      priority: 0,
      actionGroup: "",
      type: "",
      data: "",
    });
    const configs = ref({
      type: "",
      place: "",
      poseID: "",
    });
    const originConfigs = ref({
      type: "",
      place: "",
      poseID: "",
    });
    const originAction = ref({});

    const amrType = ref("");
    const modified = computed(
      () => JSON.stringify(action.value) !== JSON.stringify(originAction.value)
    );
    const modifiedConfig = computed(
      () =>
        JSON.stringify(configs.value) !== JSON.stringify(originConfigs.value)
    );

    function typeChange() {
      if (
        action.value.type.includes("load") ||
        ["lift-in", "lift-out"].includes(action.value.type)
      ) {
        action.value.data = {};
      } else {
        action.value.data = "";
      }
    }

    const typeOptions = inject("typeOptions");
    const groupOptions = inject("groupOptions");

    return {
      visible,
      action,
      incomplete: computed(
        () => action.value.device === "" || action.value.type === ""
      ),
      setAmrType(data) {
        if (amrType.value !== data.type) {
          if (action.value.actionGroup !== "amr") {
            action.value.actionGroup = data.type;
            action.value.type = "";
            typeChange();
          }
          amrType.value = data.type;
        }
      },
      show(data) {
        if (props.modify) {
          action.value = {};
          action.value = JSON.parse(JSON.stringify(data));
          if (
            action.value.type === "attach" ||
            action.value.type === "operate"
          ) {
            const list = action.value.data.split(",");
            configs.value.poseID = list[0];
            configs.value.type = list[1];
            configs.value.place = list[2];
          }
          if (action.value.type === "posture") {
            const list = action.value.data.split(",");
            configs.value.poseID = list[0];
            configs.value.type = list[1];
          }
          originConfigs.value = JSON.parse(JSON.stringify(configs.value));
          originAction.value = data;
          api
            .get(useAPIStore().centerUrl + "configs/id/" + action.value.device)
            .then((rs) => {
              amrType.value = rs.data.type;
            });
          visible.value = true;
        } else {
          action.value.priority = props.priority;
          action.value.planID = props.plan.id;
          action.value.device = props.device;
          configs.value = {
            type: "",
            place: "",
            poseID: "",
          };
          if (props.device) {
            api
              .get(
                useAPIStore().centerUrl + "configs/id/" + action.value.device
              )
              .then((rs) => {
                amrType.value = rs.data.type;
              });
          }
          visible.value = true;
        }
      },
      addAction() {
        if (action.value.type === "attach" || action.value.type === "operate") {
          configs.value.type =
            action.value.type === "attach" ? "N" : configs.value.type;
          action.value.data =
            configs.value.poseID +
            "," +
            configs.value.type +
            "," +
            configs.value.place;
        }
        if (action.value.type === "posture") {
          action.value.data = configs.value.poseID + "," + configs.value.type;
        }
        api
          .post(useAPIStore().centerUrl + "action", action.value)
          .then((rs) => {
            if (rs.status === 200) {
              $q.notify({ message: "动作创建成功", type: "positive" });
              context.emit("refresh");
              visible.value = false;
            } else {
              console.log(rs);
              $q.notify({ message: "动作创建失败", type: "negative" });
            }
          });
      },
      modified,
      reset() {
        action.value = JSON.parse(JSON.stringify(originAction.value));
        configs.value = JSON.parse(JSON.stringify(originConfigs.value));
      },
      update() {
        if (action.value.type === "attach" || action.value.type === "operate") {
          configs.value.type =
            action.value.type === "attach" ? "N" : configs.value.type;
          action.value.data =
            configs.value.poseID +
            "," +
            configs.value.type +
            "," +
            configs.value.place;
        }
        if (action.value.type === "posture") {
          action.value.data = configs.value.poseID + "," + configs.value.type;
        }
        api.put(useAPIStore().centerUrl + "action", action.value).then((rs) => {
          console.log(rs);
          $q.notify({ message: "修改动作成功", type: "positive" });
          context.emit("refresh");
          visible.value = false;
        });
      },
      remove() {
        $q.dialog({
          title: "删除动作",
          message: "是否要删除该动作？",
          cancel: true,
          persistent: true,
        }).onOk(() => {
          api
            .delete(useAPIStore().centerUrl + "action/" + action.value.id)
            .then((rs) => {
              console.log(rs);
              context.emit("refresh");
              $q.notify({ message: "动作删除成功", type: "positive" });
              visible.value = false;
            });
        });
      },
      execute() {
        api
          .post(useAPIStore().centerUrl + "action/execute", action.value)
          .then((rs) => {
            if (rs.status === 200) {
              $q.notify({ type: "positive", message: "指令已下发" });
              visible.value = false;
            }
          });
      },
      groupChange() {
        action.value.type = "";
        typeChange();
      },
      typeChange,
      groups: computed(() =>
        groupOptions.filter((item) =>
          ["amr", amrType.value].includes(item.value)
        )
      ),
      booleanOption,
      basicMove: computed(() =>
        typeOptions.filter((item) => item.type === "amr")
      ),
      actionTypes: computed(() =>
        typeOptions.filter((item) => item.type === action.value.actionGroup)
      ),
      placeOption: ref([
        { label: "车头", value: "FRONT" },
        { label: "车尾", value: "BACK" },
      ]),
      configs,
      modifiedConfig,
    };
  },
};
</script>
